﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Lime49;

namespace LockCrypt.Core {
    /// <summary>
    /// A field in an account or template
    /// </summary>
    public class FieldBase : IField {
        public virtual string Name { get; set; }
        public virtual string Value { get; set; }
        public virtual FieldMetaData Meta { get; set; }
        public virtual int SortIndex { get; set; }

        public FieldBase() {

        }

        /// <summary>
        /// Converts this field to an XElement.
        /// </summary>
        /// <returns>An XElement representing this field.</returns>
        public XElement ToXElement() {
            XElement xField = new XElement("field",
                new XElement("title", HtmlUtils.HtmlEncode(this.Name)),
                new XAttribute("meta", ((int)this.Meta)),
                new XAttribute("sortindex", this.SortIndex),
                new XElement("value", HtmlUtils.HtmlEncode(this.Value)));
            return xField;
        }

        /// <summary>
        /// Initializes a new <see cref="FieldBase"/> from an XElement.
        /// </summary>
        /// <param name="element">The XElement containing the field data.</param>
        /// <returns>
        /// The field contained in the specified XElement.
        /// </returns>
        public static IField FromXElement(XElement element) {
            IField field = new FieldBase() {
                Name = HtmlUtils.HtmlDecode(element.Element("title").Value),
                Meta = (FieldMetaData)Enum.Parse(typeof(FieldMetaData), element.Attribute("meta").Value, true),
                SortIndex = int.Parse(element.Attribute("sortindex").Value),
                Value = HtmlUtils.HtmlDecode(element.Element("value").Value)
            };
            return field;
        }

        /// <summary>
        /// Creates a deep copy of this field.
        /// </summary>
        /// <returns>A clone of this field.</returns>
        public virtual IField Clone() {
            FieldBase clone = new FieldBase() {
                Name = this.Name,
                Value = this.Value,
                Meta = this.Meta,
                SortIndex = this.SortIndex
            };
            return clone;
        }

        public override string ToString() {
            return string.Format("#{0}: {1} - {2} ({3})", SortIndex, Name, Value, Meta);
        }

        /// <summary>
        /// Checks whether a meta data value has a metadsata flag set.
        /// </summary>
        /// <param name="metaDataToCheck">The meta data to check.</param>
        /// <param name="flag">The meta data flag whose state to check.</param>
        /// <returns>True if the data contains the flag, otherwise <c>false</c></returns>
        public static bool GetMetaState(string metaDataToCheck, FieldMetaData flag) {
            FieldMetaData metaType = (FieldMetaData)Enum.Parse(typeof(FieldMetaData), metaDataToCheck, true);
            return GetMetaState(metaType, flag);
        }

        /// <summary>
        /// Checks whether a meta data value has a metadsata flag set.
        /// </summary>
        /// <param name="metaDataToCheck">The meta data to check.</param>
        /// <param name="flag">The meta data flag whose state to check.</param>
        /// <returns>True if the data contains the flag, otherwise <c>false</c></returns>
        public static bool GetMetaState(FieldMetaData metaDataToCheck, FieldMetaData flag) {
            return ((metaDataToCheck & flag) == flag);
        }
    }
}
